package com.hh.service.service.impl.merchant;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.hh.common.exception.HhException;
import com.hh.common.model.merchant.MerchantAdmin;
import com.hh.common.model.merchant.MerchantMenu;
import com.hh.common.model.merchant.MerchantRole;
import com.hh.common.model.merchant.MerchantRoleMenu;
import com.hh.common.request.PageParamRequest;
import com.hh.common.request.SystemRoleRequest;
import com.hh.common.request.SystemRoleSearchRequest;
import com.hh.common.response.RoleInfoResponse;
import com.hh.common.utils.SecurityUtil;
import com.hh.common.vo.MenuCheckTree;
import com.hh.common.vo.MenuCheckVo;
import com.hh.common.vo.merchant.MerLoginUserVo;
import com.hh.service.dao.merchant.MerchantRoleDao;
import com.hh.service.service.merchant.MerchantMenuService;
import com.hh.service.service.merchant.MerchantRoleMenuService;
import com.hh.service.service.merchant.MerchantRoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class MerchantRoleServiceImpl extends ServiceImpl<MerchantRoleDao, MerchantRole> implements MerchantRoleService {

    @Resource
    private MerchantRoleDao dao;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private MerchantRoleMenuService merchantRoleMenuService;

    @Autowired
    private MerchantMenuService merchantMenuService;

    @Override
    public List<MerchantRole> getAllList() {
        LambdaQueryWrapper<MerchantRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MerchantRole::getStatus, true);
        lambdaQueryWrapper.orderByAsc(MerchantRole::getId);
        return dao.selectList(lambdaQueryWrapper);
    }

    @Override
    public List<MerchantRole> getList(SystemRoleSearchRequest request, PageParamRequest pageParamRequest) {
        String merId = SecurityUtil.getMerLoginUserVo().getUser().getMerId();

        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<MerchantRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(MerchantRole::getId, MerchantRole::getRoleName, MerchantRole::getStatus,
                MerchantRole::getCreateTime, MerchantRole::getUpdateTime,MerchantRole::getIsSuperAdmin);
        lambdaQueryWrapper.eq(MerchantRole::getMerId,merId);
        if (ObjectUtil.isNotNull(request.getStatus())) {
            lambdaQueryWrapper.eq(MerchantRole::getStatus, request.getStatus());
        }
        if (ObjectUtil.isNotNull(request.getRoleName())) {
            lambdaQueryWrapper.like(MerchantRole::getRoleName, request.getRoleName());
        }
        lambdaQueryWrapper.orderByAsc(MerchantRole::getId);
        return dao.selectList(lambdaQueryWrapper);
    }

    @Override
    public Boolean add(SystemRoleRequest systemRoleRequest) {
        MerchantAdmin user = SecurityUtil.getMerLoginUserVo().getUser();

        if (existName(systemRoleRequest.getRoleName(), null)) {
            throw new HhException("角色名称重复");
        }
        List<Integer> ruleList = Stream.of(systemRoleRequest.getRules().split(",")).map(Integer::valueOf).distinct().collect(Collectors.toList());
        MerchantRole merchantRole = new MerchantRole();
        BeanUtils.copyProperties(systemRoleRequest, merchantRole);
        merchantRole.setId(null);
        merchantRole.setRules("");
        merchantRole.setMerId(user.getMerId());
        return transactionTemplate.execute(e -> {
            boolean save = save(merchantRole);
            if (!save) {
                return Boolean.FALSE;
            }
            List<MerchantRoleMenu> roleMenuList = ruleList.stream().map(rule -> {
                MerchantRoleMenu roleMenu = new MerchantRoleMenu();
                roleMenu.setRid(merchantRole.getId());
                roleMenu.setMenuId(rule);
                return roleMenu;
            }).collect(Collectors.toList());
            merchantRoleMenuService.saveBatch(roleMenuList, 100);
            return Boolean.TRUE;
        });
    }

    @Override
    public Boolean delete(Integer id) {
        MerchantAdmin user = SecurityUtil.getMerLoginUserVo().getUser();

        MerchantRole merchantRole = getById(id);
        if (ObjectUtil.isNull(merchantRole)) {
            throw new HhException("角色已删除");
        }
        if(merchantRole.getIsSuperAdmin()){
            throw new HhException("不能删除超级管理员");
        }
        if(!merchantRole.getMerId().equals(user.getMerId())){
            throw new HhException("商户异常，删除失败");
        }
        return transactionTemplate.execute(e -> {
            dao.deleteById(id);
            merchantRoleMenuService.deleteByRid(id);
            return Boolean.TRUE;
        });
    }

    @Override
    public Boolean edit(SystemRoleRequest systemRoleRequest) {
        MerchantAdmin user = SecurityUtil.getMerLoginUserVo().getUser();
        MerchantRole role = getById(systemRoleRequest.getId());
        if (ObjectUtil.isNull(role)) {
            throw new HhException("角色不存在");
        }
        if (!role.getRoleName().equals(systemRoleRequest.getRoleName())) {
            if (existName(systemRoleRequest.getRoleName(), systemRoleRequest.getId())) {
                throw new HhException("角色名称重复");
            }
        }
        if(!role.getMerId().equals(user.getMerId())){
            throw new HhException("商户异常，修改失败");
        }
        MerchantRole merchantRole = new MerchantRole();
        BeanUtils.copyProperties(systemRoleRequest, merchantRole);
        merchantRole.setRules("");
        List<Integer> ruleList = Stream.of(systemRoleRequest.getRules().split(",")).map(Integer::valueOf).distinct().collect(Collectors.toList());
        List<MerchantRoleMenu> roleMenuList = ruleList.stream().map(rule -> {
            MerchantRoleMenu roleMenu = new MerchantRoleMenu();
            roleMenu.setRid(merchantRole.getId());
            roleMenu.setMenuId(rule);
            return roleMenu;
        }).collect(Collectors.toList());
        return transactionTemplate.execute(e -> {
            updateById(merchantRole);
            merchantRoleMenuService.deleteByRid(merchantRole.getId());
            merchantRoleMenuService.saveBatch(roleMenuList, 100);
            return Boolean.TRUE;
        });
    }

    @Override
    public RoleInfoResponse getInfo(Integer id) {
        MerchantRole merchantRole = getById(id);
        if (ObjectUtil.isNull(merchantRole)) {
            throw new HhException("角色不存在");
        }
        MerLoginUserVo merLoginUserVo = SecurityUtil.getMerLoginUserVo();
        MerchantAdmin user = merLoginUserVo.getUser();
        // 查询角色对应的菜单(权限)
        List<MerchantMenu> menuList = merchantMenuService.getCacheList(user.getMerId());
        List<Integer> menuIdList = merchantRoleMenuService.getMenuListByRid(id);

        List<MenuCheckVo> menuCheckVoList = menuList.stream().map(menu -> {
            MenuCheckVo menuCheckVo = new MenuCheckVo();
            BeanUtils.copyProperties(menu, menuCheckVo);
            if (menuIdList.contains(menu.getId())) {
                menuCheckVo.setChecked(true);
            } else {
                menuCheckVo.setChecked(false);
            }
            return menuCheckVo;
        }).collect(Collectors.toList());

        RoleInfoResponse response = new RoleInfoResponse();
        BeanUtils.copyProperties(merchantRole, response);
        response.setMenuList(new MenuCheckTree(menuCheckVoList).buildTree());
        return response;
    }

    @Override
    public Boolean updateStatus(Integer id, Boolean status) {
        MerchantAdmin user = SecurityUtil.getMerLoginUserVo().getUser();
        MerchantRole role = getById(id);
        if (ObjectUtil.isNull(role)) {
            throw new HhException("身份不存在");
        }
        if(!role.getMerId().equals(user.getMerId())){
            throw new HhException("商户异常，修改失败");
        }
        if (role.getStatus().equals(status)) {
            return true;
        }
        role.setStatus(status);
        return updateById(role);
    }

    @Override
    public List<MerchantRole> getRolesListByIds(List<Integer> rolesList) {
        return dao.getRolesListByIds(rolesList);
    }

    /**
     * 判断角色名称是否存在
     * @param roleName 角色名称
     * @param id 角色id
     * @return Boolean
     */
    private Boolean existName(String roleName, Integer id) {
        LambdaQueryWrapper<MerchantRole> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantRole::getRoleName, roleName);
        if (ObjectUtil.isNotNull(id)) {
            lqw.ne(MerchantRole::getId, id);
        }
        lqw.last(" limit 1");
        Integer count = dao.selectCount(lqw);
        return count > 0;
    }
}
